Many operating systems are divided into modules that have direct access or privilege to hardware, known as kernels, and programs that must request access to hardware from the kernels, known as user space applications. Kernels are typically the central modules of an operating system, having direct access to a computer's memory, disk drives, network adaptors and other resources, and are typically stored in the computer's main memory. User space applications, on the other hand, have only limited access to a computer's resources and normally have to request access to memory, drives and other hardware from the kernels. As an example, if a user space application, such as a word processing program, has to access a disk drive, the user space application will request that the kernel perform the tasks necessary to carry out the disk access operation. Thus, the kernel acts as an interface between the hardware and user space applications. The interaction between kernels and user space applications, in the prior art, is typically limited to the servicing of hardware calls by the kernel.
Two basic kernel architectures have arisen in modern operating systems, monolithic and micro-kernel. In a monolithic system, a single piece of code has privileges to the resources of the computer and has access to all the data structures and routines of the kernel. The open-source operating system Linux uses a monolithic kernel architecture. In a micro-kernel architecture, conversely, access to hardware, data structures and routines is distributed among multiple specialized kernels. In this architecture, each device may be controlled by its own kernel (or device driver) that has access to only that device. The micro-kernel architecture is employed by the popular Windows Operating system produced by Redmond, Wash. based Microsoft Corporation. In either system, the kernels allow the operating system to centralize access control to the hardware of a computer. Because a kernel can balance service requests from multiple user space applications without conflict, the operating system can more effectively multitask. Moreover, because kernels are generally implemented at a lower level (i.e., closer to the hardware), they allow for more efficient hardware management than if hardware access was managed at the user space level.
Kernels are typically designed to be very light weight. This is done because the kernels stay in the main memory of the computer and light weight code minimizes memory usage. In order to keep the kernels small, each kernel is generally provided with only the limited amount of code required to carry out simple mathematics and hardware access functions, but not additional code to carry out more complicated functions. However, the gradual importation of more complex processing to kernel space can be seen in the evolution of the Microsoft Windows operating system. With each new version of Windows, the device drivers that operate in kernel space have become increasingly more complex. This has allowed more complicated operations to be performed at the kernel level where processing is generally more efficient. Even these kernels, however, do not typically carry out complex mathematical operations.
Placing operations at the kernel level can have the advantage of increased efficiency, but can also have several substantial disadvantages. As an initial problem, kernels are generally more difficult to program than user space applications, leading to increased programming time. Moreover, because kernels stay in main memory, larger kernels require more memory to be permanently employed during the operation of a computer. Also, as the code size of the kernel grows, the likelihood of device mismanagement or a bug in the kernel increases. This is a particular problem as kernels are notoriously difficult to debug and failure of a kernel to run properly can lead to catastrophic failure in a computer (e.g., a “blue screen” crash in the case of memory manager failure).
Because of these difficulties, complex calculations in prior art systems typically take place in user space. For example, authentication routines that require complex mathematical operations have not typically been implemented in the kernel layer. The difficulty in implementing authentication at the kernel layer, particularly for protocols such as iSCSI, results, at least in part, from the fact that authentication protocols generally need the support of a complex multi-precision math library to process authentication challenges and keys, and to handle other complex processes involving large numbers. In prior art systems, this required that authentication be carried out in user space because a kernel that could fully support authentication routines would be too large and unstable to be practicably implemented. The kernel's only involvement in the authentication routine was to service hardware calls, thus maintaining the strict functional boundary between the kernels and user space applications.